module expand #(
    parameter int unsigned WIDTH = 8,
    parameter int unsigned N     = 4
) (
    input  logic               clk,
    input  logic               rst_n,
    input  logic [  WIDTH-1:0] in_data,
    input  logic               in_valid,
    output logic               in_ready,
    output logic [WIDTH*N-1:0] out_data,
    output logic               out_valid,
    input  logic               out_ready
);

    generate
        if (N == 1) begin : gen_passthrough
            assign in_ready  = out_ready;
            assign out_valid = in_valid;
            assign out_data  = in_data;
        end else begin : gen_expand
            logic [    WIDTH*N-1:0] data_buffer;
            logic [$clog2(N+1)-1:0] cntr;
            logic                   buffer_full;

            assign in_ready  = !buffer_full || out_ready;
            assign out_valid = buffer_full;
            assign out_data  = data_buffer;

            always_ff @(posedge clk or negedge rst_n) begin
                if (!rst_n) begin
                    data_buffer <= '0;
                    cntr        <= 0;
                    buffer_full <= 1'b0;
                end else begin
                    if ((in_valid && in_ready) && (out_valid && out_ready)) begin
                        data_buffer[0*WIDTH+:WIDTH] <= in_data;
                        cntr                        <= 1;
                        buffer_full                 <= 1'b0;
                    end else if (in_valid && in_ready) begin
                        data_buffer[cntr*WIDTH+:WIDTH] <= in_data;
                        if (cntr == N - 1) begin
                            cntr        <= 0;
                            buffer_full <= 1'b1;
                        end else begin
                            cntr <= cntr + 1;
                        end
                    end else if (out_valid && out_ready) begin
                        buffer_full <= 1'b0;
                    end
                end
            end
        end
    endgenerate

endmodule
